package cn.tedu.submarine;
import org.omg.CORBA.PUBLIC_MEMBER;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class World extends JPanel{
    public static final int WIDTH = 641;
    public static final int HEIGHT = 479;
    public static final int RUNNING = 0;
    public static final int GAME_OVER = 1;
    private int state = RUNNING;

    private BattleShip ship = new BattleShip();
    private SeaObject[] submarines = {};
    private Mine[] mines = {};
    private Bomb[] bombs = {};


    public SeaObject nextSubmarine() {
        Random random = new Random();
        int type = random.nextInt(20);
        if(type < 10) {
            return new ObserveSubmarine();
        }else if(type < 15) {
            return new MineSubmarine();
        }else {
            return new TorpedoSubmarine();
        }
    }

    @Override
    public void paint(Graphics g) {
        switch (state) {
            case RUNNING:
                Images.sea.paintIcon(null,g,0,0);
                ship.paintImage(g);
                for (int i = 0; i < submarines.length; i++) {
                    submarines[i].paintImage(g);
                }
                for (int i = 0; i < mines.length; i++) {
                    mines[i].paintImage(g);
                }
                for (int i = 0; i < bombs.length; i++) {
                    bombs[i].paintImage(g);
                }
                g.drawString("SCORE:" + score,200,50);
                g.drawString("LIFE:" + ship.getLife(),400,50);
                break;
            case GAME_OVER:
                Images.gameOver.paintIcon(null,g,0,0);
                break;
        }

    }

    public void checkGameOver() {
        if(ship.getLife() < 0) {
            state = GAME_OVER;
        }
    }
    private int subEnterIndex = 0;
    public void submarineEnterAction() {
        ++subEnterIndex;
        if(subEnterIndex % 40 == 0) {
            SeaObject seaObject = nextSubmarine();
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = seaObject;
        }
    }
    private int mineEnterIndex = 0;
    public void mineEnterAction() {
        ++mineEnterIndex;
        if(mineEnterIndex % 100 == 0) {
            for (int i = 0; i < submarines.length; i++) {
                if(submarines[i] instanceof MineSubmarine) {
                    Mine mine = ((MineSubmarine) submarines[i]).shootMine();
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    mines[mines.length - 1] = mine;
                }
            }
        }
    }
    public void moveAction() {
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].move();
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].move();
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].move();
        }
    }

    public void outOfBoundsAction() {
        for (int i = 0; i < submarines.length; i++) {
            if(submarines[i].isOutOfBounds() || submarines[i].isDead()) {
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            }
        }
        for (int i = 0; i < mines.length; i++) {
            if(mines[i].isOutOfBounds() || mines[i].isDead()) {
                mines[i] = mines[mines.length-1];
                mines = Arrays.copyOf(mines,mines.length-1);
            }
        }
        for (int i = 0; i < bombs.length; i++) {
            if(bombs[i].isOutOfBounds() || bombs[i].isDead()) {
                bombs[i] = bombs[bombs.length-1];
                bombs = Arrays.copyOf(bombs,bombs.length-1);
            }
        }
    }
    private int score = 0;
    public void hitSubmarineAction() {
        for (int i = 0; i < bombs.length; i++) {
            Bomb b = bombs[i];
            for (int j = 0; j < submarines.length; j++) {
                SeaObject s = submarines[j];
                if(s.isHit(b)) {
                    b.goDead();
                    s.goDead();
                    if(s instanceof OwnScore) {
                        OwnScore s1 = (OwnScore) s;
                        score += s1.getScore();
                    }else if(s instanceof OwnLife) {
                        OwnLife s1 = (OwnLife) s;
                        int num = s1.getLife();
                        ship.addLife(num);
                    }
                }

            }
        }
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            if(m.isHit(ship)) {
                m.goDead();
                ship.minusLife(1);
            }
        }
    }

    public void action() {
        if(state == RUNNING) {
            KeyAdapter k = new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {//当按键抬起时自动执行
                    if(e.getKeyCode() == KeyEvent.VK_J) {
                        Bomb bomb = ship.shootBomb();
                        bombs = Arrays.copyOf(bombs,bombs.length+1);
                        bombs[bombs.length-1] = bomb;
                    }else if(e.getKeyCode() == KeyEvent.VK_A) {
                        ship.moveLeft();
                    }else if (e.getKeyCode() == KeyEvent.VK_D) {
                        ship.moveRight();
                    }
                }
            };
            this.addKeyListener(k);
            Timer timer = new Timer();
            int interval = 10;//定时间隔（以毫秒为单位）
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    submarineEnterAction();
                    mineEnterAction();
                    moveAction();
                    outOfBoundsAction();
                    hitSubmarineAction();
                    checkGameOver();
                    repaint();
                }
            }, interval, interval);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16,HEIGHT+39);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);//这句话进行了两步（1）设置窗口可见，（2）尽快调paint方法
        world.action();
    }
}
